﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;

namespace ThreadDemo
{
    class Program
    {

        static int bookCount = 1000;
        readonly static object objLock = new object();

        static void Main(string[] args)
        {
            //线程（Thread）是进程中的基本执行单元，是操作系统分配CPU时间的基本单位
            //一个进程可以包含若干个线程，在进程入口执行的第一个线程被视为这个进程的主线程。

            //多线程的优点：可以同时完成多个任务；可以使程序的响应速度更快；
            //可以让占用大量处理时间的任务或当前没有进行处理的任务定期将处理时间让给别的任务；
            //可以随时停止任务；可以设置每个任务的优先级以优化程序性能。

            //多线程的缺点：线程也是程序，所以线程需要占用内存，线程越多，占用内存也越多。
            //多线程需要协调和管理，所以需要占用CPU时间以便跟踪线程。
            //线程之间对共享资源的访问会相互影响，必须解决争用共享资源的问题。
            //线程太多会导致控制太复杂，最终可能造成很多程序缺陷。

            //Console.WriteLine("主线程id为{0}",Thread.CurrentThread.ManagedThreadId);

            ////创建一个新的线程
            //Thread thread = new Thread(() => 
            //{
            //    int threadId = Thread.CurrentThread.ManagedThreadId;
            //    Console.WriteLine("线程Id为：{0}.线程名字为：{1}....开启了一个新的线程，并执行了", threadId, Thread.CurrentThread.Name);

            //});

            //thread.Name = "用户自己开启的线程";
            ////开始运行线程
            //thread.Start();

            //Thread.Sleep(2000);

            //前台线程：只有所有的前台线程都结束，应用程序才能结束。默认情况下创建的线程都是前台线程
            //后台线程：只要所有的前台线程结束，后台线程自动结束。通过Thread.IsBackground设置后台线程。
            //必须在调用Start方法之前设置线程的类型，否则一旦线程运行，将无法改变其类型。

            Thread thread = new Thread(() => 
            {
                for (int i = 0; i < 10; i++)
                {
                    Thread.Sleep(200);
                    Console.WriteLine("前台线程执行了{0}次",i+1);
                }
                Console.WriteLine("前台线程执行完成");
            });

            Thread thread2 = new Thread(() => 
            {
                for (int i = 0; i < 20; i++)
                {
                    Thread.Sleep(200);
                    Console.WriteLine("后台线程执行了{0}次", i + 1);
                }
                Console.WriteLine("后台线程执行完成");
            });
            //设置后台线程
            //thread2.IsBackground = true;
            thread.Start();
            thread2.Start();
            //线程池：由于线程的创建和销毁需要耗费一定的开销，过多的使用线程会造成内存资源的浪费，
            //出于对性能的考虑，于是引入了线程池的概念。线程池维护一个请求队列，线程池的代码从队列提取任务，
            //然后委派给线程池的一个线程执行，线程执行完不会被立即销毁，这样既可以在后台执行任务，又可以减少线程创建和销毁所带来的开销。
            //线程池线程默认为后台线程（IsBackground）

            //for (int i = 0; i < 10; i++)
            //{
            //    ThreadPool.QueueUserWorkItem((a) =>
            //    {
            //        Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
            //    });
            //}




            #region 线程同步,线程安全
            //Thread thread1 = new Thread(() =>
            //{
            //    while (true)
            //    {
            //        if (bookCount > 0)
            //        {
            //            bookCount -= 1;
            //            Console.WriteLine("线程：" + Thread.CurrentThread.ManagedThreadId + "，卖掉了一本书，" + "剩余" + bookCount + "本书");

            //        }
            //        else
            //        {
            //            break;
            //        }


            //    }
            //});
            //Thread thread2 = new Thread(() =>
            //{
            //    while (true)
            //    {
            //        if (bookCount > 0)
            //        {
            //            bookCount -= 1;
            //            Console.WriteLine("线程：" + Thread.CurrentThread.ManagedThreadId + "，卖掉了一本书，" + "剩余" + bookCount + "本书");

            //        }
            //        else
            //        {
            //            break;
            //        }


            //    }
            //});
            //Thread thread3 = new Thread(() =>
            //{
            //    while (true)
            //    {

            //        if (bookCount > 0)
            //        {
            //            bookCount -= 1;
            //            Console.WriteLine("线程：" + Thread.CurrentThread.ManagedThreadId + "，卖掉了一本书，" + "剩余" + bookCount + "本书");

            //        }
            //        else
            //        {
            //            break;
            //        }
            //    }
            //});
            //thread1.Start();
            //thread2.Start();
            //thread3.Start();



            #endregion


            //Console.ReadLine();
        }

        public static void Method1(int count)
        {
            for (int i = 1; i < count; i++)
            {
                Thread.Sleep(200);
                Console.WriteLine("线程id为：{0}。线程名称为{1}.执行了{1}次", Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.Name, i);
            }
            Console.WriteLine(Thread.CurrentThread.Name + "执行完成");
        }

    }
}
